package com.bawei.lib_common.base

import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.Lifecycle
import com.alibaba.android.arouter.launcher.ARouter
import com.bawei.lib_common.R
import com.bawei.lib_common.base.state.Empty
import com.bawei.lib_common.base.state.Failed
import com.bawei.lib_common.base.state.Loading
import com.bawei.lib_common.base.state.RequestEvent
import com.bawei.lib_common.base.state.Success
import com.bawei.lib_common.observeWithLifecycle
import com.bawei.lib_common.utils.ToastUtils
import com.bawei.myclub.base.mvvm.view.BaseFragment
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.flow.SharedFlow


/**
 *作者：lxy
 *功能:
 *时间：2025/5/25
 */
const val TAG = "[BaseActivity]"

abstract class BaseActivity<VM : BaseViewModel, VDB : ViewDataBinding> : AppCompatActivity() {

    abstract val mLayoutResId: Int //布局id

    protected lateinit var mBinding: VDB //binding

    protected lateinit var mRootView: ViewGroup

    protected var mLoadingView: View? = null
    abstract val mViewModel: VM

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //ARouter传值自动注入
        ARouter.getInstance().inject(this)

        mBinding = DataBindingUtil.setContentView(this, mLayoutResId)

        mBinding.lifecycleOwner = this
        //全局加载状态
        initGlobalView()
        //状态栏
        initStatusBar()
        initView()
        initListener()
        initData()
    }

    abstract fun initView()

    abstract fun initListener()

    abstract fun initData()

    open fun initStatusBar() {

    }

    private fun initGlobalView() {
        mRootView = window.decorView as ViewGroup
        initLoadingView()
    }

    /**
     * 初始化加载中界面
     */
    private fun initLoadingView() {
        if (mLoadingView == null) {
            mLoadingView = layoutInflater.inflate(R.layout.dialog_common_progress, mRootView, false)
            mLoadingView!!.setOnClickListener(View.OnClickListener { v: View? -> })
            setLoadingViewVisible(false)
            mRootView.addView(mLoadingView)
        }
    }

    /**
     * 设置显示或隐藏
     */
    open fun setLoadingViewVisible(show: Boolean, msg: String = "") {
        mLoadingView?.let {
            val textView = it.findViewById<TextView>(R.id.tv_text)
            if (show && msg.isNotEmpty())
                textView.text = msg
            if (show) it.visibility = View.VISIBLE else it.visibility = View.GONE
        }
    }


    // 添加通用的状态监听，这里只做Loading的隐藏，显示和错误消息Toast
    open fun addCommonStateListener(stateListener: SharedFlow<RequestEvent>) {
        stateListener.observeWithLifecycle(this, Lifecycle.State.STARTED) {
            when (it) {
                is Success -> {
                    setLoadingViewVisible(false)
                }

                is Loading -> {
                    setLoadingViewVisible(true)
                }

                is Failed -> {
                    setLoadingViewVisible(false)
                    onLoadFailed(it.message)
                }

                is Empty -> {
                    setLoadingViewVisible(false)
                    ToastUtils.showLong(this, "数据为空")
                }

            }
        }
    }

    //失败展示
    open fun onLoadFailed(msg: String) {}

    open val mPageCanBack: Boolean = true //是否可返回
    private var lastPressBack = 0L //上一次点击返回的时间戳

    /**
     * 点击返回处理
     * 1.当前activity是否可返回（A--》B B可返回的 A不可返回）
     *  可返回：默认返回
     *  不可返回：
     *      2.当前activity有无fragment
     *          无：退出app
     *          有：判断fragment是否可返回
     *              可返回：默认返回
     *              不可返回：退出app
     */
    override fun onBackPressed() {
        val timeStamp = System.currentTimeMillis()
        //1.当前activity是否可返回
        if (mPageCanBack) {
            Log.d(TAG, "返回上一个activity: ")
            super.onBackPressed()
            return
        }
        //2.当前activity有无fragment
        val fragments = supportFragmentManager.fragments.filterIsInstance<BaseFragment<*, *>>()
        //无fragment：退出app
        if (fragments.isEmpty() && isPressBackToExitApp(timeStamp)) {
            Log.d(TAG, "此activity无fragment，关闭app: ")
            super.onBackPressed()
            return
        }
        //有fragment
        for (fragment in fragments) {
            if (fragment.isVisible) {
                //可返回
                if (fragment.mCanBack) {
                    super.onBackPressed()
                    return
                }
                //不可返回:退出app
                if (isPressBackToExitApp(timeStamp)) {
                    super.onBackPressed()
                    return
                }
            }
        }

    }

    /**
     * 退出app
     */
    private fun isPressBackToExitApp(timeStamp: Long): Boolean {
        if (lastPressBack == timeStamp) {
            return false
        }
        if (timeStamp - lastPressBack < 2000) {
            return true
        } else {
            Toast.makeText(this, "再按一次退出", Toast.LENGTH_SHORT).show()
            lastPressBack = timeStamp
            return false
        }

    }

    open fun showToast(stringRes: String) {
        Snackbar.make(window.decorView, stringRes, Snackbar.LENGTH_LONG).show()
    }

    open fun showToast(view: View?, stringRes: Int) {
        Snackbar.make(view ?: window.decorView, stringRes, Snackbar.LENGTH_LONG).show()
    }

    /**
     * 隐藏键盘
     */
    fun hideKeyboard(view: View) {
        (view.context
            .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?)?.hideSoftInputFromWindow(view.windowToken, 0)
    }
    /**
     * 显示键盘
     */
    fun showSoftKeyBoard(view: View) {
        view.requestFocus()
        view.postDelayed({
            val imm = view.context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
            imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
        }, 200)

    }

    fun dismissKeyboard() {
        try {
            val view = window.peekDecorView()
            if (view != null) {
                val im = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
                im.hideSoftInputFromWindow(view.windowToken, 0)
            }
        } catch (e: Exception) {
        }
    }


}